<style scoped></style>

<template>
    <div class="row">
        <el-checkbox v-model="node.active">Node</el-checkbox>
        <el-input style="margin: 0 15px;" size="small" v-model="node.name"></el-input>
        <el-button round size="small" :icon="Position" @click="drawNode"></el-button>
        <el-button round size="small" :icon="Document" @click="gm.toConsole(node)"></el-button>
    </div>

    <div class="row-start">
        <el-text class="span-title" truncated>Position</el-text>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.x">
            <template #suffix>
                <span>X</span>
            </template>
        </el-input-number>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.y">
            <template #suffix>
                <span>Y</span>
            </template>
        </el-input-number>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.z">
            <template #suffix>
                <span>Z</span>
            </template>
        </el-input-number>
    </div>

    <div class="row-start">
        <el-text class="span-title" truncated>Rotation</el-text>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.rotX">
            <template #suffix>
                <span>X</span>
            </template>
        </el-input-number>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.rotY">
            <template #suffix>
                <span>Y</span>
            </template>
        </el-input-number>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.rotZ">
            <template #suffix>
                <span>Z</span>
            </template>
        </el-input-number>
    </div>

    <div class="row-start">
        <el-text class="span-title" truncated>Scale</el-text>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.scaleX">
            <template #suffix>
                <span>X</span>
            </template>
        </el-input-number>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.scaleY">
            <template #suffix>
                <span>Y</span>
            </template>
        </el-input-number>
        <el-input-number size="small" :controls="false" :step="0.1" v-model="Model.scaleZ">
            <template #suffix>
                <span>Z</span>
            </template>
        </el-input-number>
    </div>

    <div class="row-start">
        <el-text class="span-title" truncated>Mobility</el-text>
        <el-select v-model="node.mobility" size="small">
            <el-option v-for="item in mobility" :key="item.value" :label="item.name" :value="item.value" />
        </el-select>
    </div>

    <div class="row-start">
        <el-text class="span-title" truncated>Layer</el-text>
        <el-select v-model="node.layer" size="small">
            <el-option v-for="item in layer" :key="item.value" :label="item.name" :value="item.value" />
        </el-select>
    </div>
</template>

<script lang="ts" setup>
import { Position, Document } from '@element-plus/icons-vue'
import gm from './gm'

const mobility = [
    {name: 'Static', value: 0},
    {name: 'Stationary', value: 1},
    {name: 'Movable', value: 2},
]
const layer = cc.Layers.BitMask.__bitmask__
const props = defineProps<{
    node: CCTreeNode,
    update: Number,
}>()

function getSelfBoundingBoxToWold(transform: any) {
    let _worldMatrix = cc.mat4();
    if (transform.node.parent) {
        transform.node.parent.getWorldMatrix(_worldMatrix);
        let parentMat = _worldMatrix;
        let _matrix = cc.mat4();
        cc.Mat4.fromRTS(_matrix, transform.node.getRotation(), transform.node.getPosition(), transform.node.getScale());
        const width = transform._contentSize.width;
        const height = transform._contentSize.height;
        const rect = cc.rect(-transform._anchorPoint.x * width, -transform._anchorPoint.y * height, width, height);
        cc.Mat4.multiply(_worldMatrix, parentMat, _matrix);
        rect.transformMat4(_worldMatrix);
        return rect;
    } else {
        return transform.getBoundingBox();
    }
}

function drawNode() {
    const target: any = props.node
    let rect;
    let transform = target.getComponent(cc.UITransformComponent);
    if (transform) {
        rect = getSelfBoundingBoxToWold(transform);
    } else {
        let worldPos = cc.v3();
        target.getWorldPosition(worldPos);
        rect = cc.rect(worldPos.x, worldPos.y, 0, 0);
    }
    let canvasNode = new cc.Node('Canvas');
    let scene = cc.director.getScene();
    scene.addChild(canvasNode);
    canvasNode.addComponent(cc.Canvas);
    let bgNode = new cc.Node();
    let graphics = bgNode.addComponent(cc.GraphicsComponent);
    let bgTransform = bgNode.addComponent(cc.UITransformComponent);
    canvasNode.addChild(bgNode);
    let centerPos = cc.v3(rect.center.x, rect.center.y, 0);
    let localPos = cc.v3();
    canvasNode.getComponent(cc.UITransformComponent).convertToNodeSpaceAR(centerPos, localPos);
    bgNode.setPosition(localPos);
    bgNode.layer = target.layer;
    let isZeroSize = rect.width === 0 || rect.height === 0;
    if (isZeroSize) {
        graphics.circle(0, 0, 100);
        graphics.fillColor = cc.Color.GREEN;
        graphics.fill();
    }
    else {
        bgTransform.width = rect.width;
        bgTransform.height = rect.height;
        graphics.rect(-bgTransform.width / 2, -bgTransform.height / 2, bgTransform.width, bgTransform.height);
        graphics.fillColor = new cc.Color().fromHEX('#E91E6390');
        graphics.fill();
    }
    setTimeout(() => {
        if (cc.isValid(canvasNode)) {
            canvasNode.destroy();
        }
    }, 2000)
}

class Model {
    static get node() {
        return props.node
    }

    static get x() {
        return this.node.getPosition().x
    }

    static set x(value: number) {
        const originPos = this.node.getPosition();
        this.node.setPosition(value, originPos.y, originPos.z);
    }

    static get y() {
        return this.node.getPosition().y;
    }

    static set y(value: number) {
        const originPos = this.node.getPosition();
        this.node.setPosition(originPos.x, value, originPos.z);
    }

    static get z() {
        return this.node.getPosition().z;
    }

    static set z(value: number) {
        const originPos = this.node.getPosition();
        this.node.setPosition(originPos.x, originPos.y, value);
    }

    static get rotX() {
        return this.node.eulerAngles.x;
    }

    static set rotX(value: number) {
        const ori = this.node.eulerAngles;
        ori.x = value
        this.node.eulerAngles = ori
    }

    static get rotY() {
        return this.node.eulerAngles.y
    }

    static set rotY(value: number) {
        const ori = this.node.eulerAngles
        ori.y = value
        this.node.eulerAngles = ori
    }

    static get rotZ() {
        return this.node.eulerAngles.z;
    }

    static set rotZ(value: number) {
        const ori = this.node.eulerAngles;
        ori.z = value
        this.node.eulerAngles = ori
    }

    static get scaleX() {
        return this.node.getScale().x;
    }

    static set scaleX(value: number) {
        const originScale = this.node.getScale();
        this.node.setScale(value, originScale.y, originScale.z);
    }

    static get scaleY() {
        return this.node.getScale().y;
    }

    static set scaleY(value: number) {
        const originScale = this.node.getScale();
        this.node.setScale(originScale.x, value, originScale.z);
    }

    static get scaleZ() {
        return this.node.getScale().z;
    }

    static set scaleZ(value: number) {
        const originScale = this.node.getScale();
        this.node.setScale(originScale.x, originScale.y, value);
    }
}
</script>